package com.gkzf.ai.module.system.service.auth;

import cn.binarywang.wx.miniapp.api.WxMaService;
import cn.binarywang.wx.miniapp.bean.WxMaJscode2SessionResult;
import cn.hutool.core.util.RandomUtil;
import com.gkzf.ai.framework.common.enums.UserTypeEnum;
import com.gkzf.ai.module.system.controller.admin.auth.vo.AuthLoginRespVO;
import com.gkzf.ai.module.system.controller.admin.auth.vo.WxAuthLoginReqVO;
import com.gkzf.ai.module.system.controller.admin.auth.vo.WxAuthLoginRespVO;
import com.gkzf.ai.module.system.convert.auth.AuthConvert;
import com.gkzf.ai.module.system.dal.dataobject.appUser.UsersDO;
import com.gkzf.ai.module.system.dal.dataobject.oauth2.OAuth2AccessTokenDO;
import com.gkzf.ai.module.system.dal.mysql.appUser.UsersMapper;
import com.gkzf.ai.module.system.enums.oauth2.OAuth2ClientConstants;
import com.gkzf.ai.module.system.service.appUser.UsersService;
import com.gkzf.ai.module.system.service.oauth2.OAuth2TokenService;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

/**
 * Auth Service 实现类
 *
 * @author 国科智飞
 */
@Service
@Slf4j
public class AdminWxAuthServiceImpl implements AdminWxAuthService {


    @Resource
    private WxMaService wxMaService;

    @Resource
    private UsersService usersService;

    @Value("${tenantId}")
    private Long tenantId;

    @Resource
    private OAuth2TokenService oauth2TokenService;

    @Resource
    private UsersMapper usersMapper;


    /**
     * 微信登录
     * @param reqVO 参数
     * @return
     */
    @Override
    public WxAuthLoginRespVO authLogin(WxAuthLoginReqVO reqVO) {
        try {
            // 调用 WxMaService 的 js_code_to_session 接口
            WxMaJscode2SessionResult sessionResult = wxMaService.getUserService().getSessionInfo(reqVO.getCode());
            // 从 sessionResult 中获取 openid 和 session_key
            String openid = sessionResult.getOpenid();
            String sessionKey = sessionResult.getSessionKey();
            // UnionID 在满足特定条件时才会返回
            String unionid = sessionResult.getUnionid();
            UsersDO users = usersService.getUsers(openid);
            if (users.getId() == null){
                users = new UsersDO();
                users.setMpOpenId(openid);
                users.setNickname("用户"+ RandomUtil.randomNumbers(4));
                users.setAppOpenId(sessionKey);
                users.setUnionId(unionid);
                users.setTenantId(tenantId);
                Long usersId = usersService.createUsers(users);
                users.setId(usersId);
            }
            AuthLoginRespVO tokenAfterLoginSuccess = createTokenAfterLoginSuccess(users.getId());
            WxAuthLoginRespVO wxAuthLoginRespVO = new WxAuthLoginRespVO();
            BeanUtils.copyProperties(tokenAfterLoginSuccess, wxAuthLoginRespVO);
            wxAuthLoginRespVO.setOpenId(openid);
            return wxAuthLoginRespVO;
        } catch (Exception e) {
            // 记录异常日志
            log.error("[authLogin][code({}) 登录异常]", reqVO.getCode(), e);
        }
        return null;
    }

    /**
     * 刷新令牌
     * @return 新的token
     */
    @Override
    public AuthLoginRespVO refreshToken(String refreshToken) {
        OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.refreshAccessToken(refreshToken, OAuth2ClientConstants.CLIENT_ID_DEFAULT);
        return AuthConvert.INSTANCE.convert(accessTokenDO);
    }

    private AuthLoginRespVO createTokenAfterLoginSuccess(Long userId) {
        // 创建访问令牌
        OAuth2AccessTokenDO accessTokenDO = oauth2TokenService.createAccessToken(userId, getUserType().getValue(),
                OAuth2ClientConstants.CLIENT_ID_DEFAULT, null);
        // 构建返回结果
        return AuthConvert.INSTANCE.convert(accessTokenDO);
    }

    private UserTypeEnum getUserType() {
        return UserTypeEnum.MEMBER;
    }

    @Override
    public void logout(String token, Integer logType) {
        // 删除访问令牌
         oauth2TokenService.removeAccessToken(token);
    }

}
